package com.tgh.gles2.c6.ads_phong;

import com.tgh.utils.GLGeometryTransform;
import com.tgh.utils.GLMatrixStack;
import com.tgh.utils.GLShaderManager;
import com.tgh.utils.GLTools;
import com.tgh.utils.GLTriangleBatch;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.SystemClock;
import android.util.AttributeSet;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MySurfaceView extends GLSurfaceView {

    public static final String TAG = "MySurfaceView";

    public MySurfaceView(Context context) {
        super(context);
        init();
    }

    public MySurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    
    private void init() {
        setEGLContextClientVersion(2);
        setRenderer(new SceneRenderer());
        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }
    
    private class SceneRenderer implements Renderer{

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            initData();
            initProgram();
            GLES20.glClearColor(0.7f, 0.7f, 0.7f, 1);
            GLES20.glEnable(GLES20.GL_DEPTH_TEST);
            GLES20.glEnable(GLES20.GL_CULL_FACE);
        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
                GLES20.glViewport(0, 0, width, height);
                projectionMatrix.getMatrix().loadPerspective(35f, (float)width/(float)height, 1.0f, 100);
                transformPipleLine.setMatrixStack(mvMatrix, projectionMatrix);
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);
            mvMatrix.loadIdentity();
            mvMatrix.translateV(0, 0, -4);
            float yRot=SystemClock.elapsedRealtime()/1000*30f;
            mvMatrix.rotate(yRot, 0, 1, 0);
            
            GLES20.glUseProgram(curProgram);
            GLES20.glUniform4fv(iAmbientColor, 1, ambientColor, 0);
            GLES20.glUniform4fv(iDiffuseColor, 1, diffuseColor, 0);
            GLES20.glUniform4fv(iSpecularColor, 1, specularColor, 0);
            GLES20.glUniform3fv(iLightPostion, 1, lightPostion, 0);
            GLES20.glUniformMatrix3fv(iNormalMatrix, 1, false, transformPipleLine.getNormalMatrix(true).getArray(), 0);
            GLES20.glUniformMatrix4fv(iMvMatrix, 1, false, mvMatrix.getMatrix().getArray(), 0);
            GLES20.glUniformMatrix4fv(iMvpMatrix, 1, false, transformPipleLine.getModelViewProjectionMatrix().getArray(), 0);
            
            torusBatch.draw();
            
        }
        
        private void initProgram() {
            String vpSrc = GLShaderManager.readFileFromAssets(getContext(), "ADSPhong.vp");
            String fpSrc = GLShaderManager.readFileFromAssets(getContext(), "ADSPhong.fp");
            curProgram = GLShaderManager.createProgram(
                    vpSrc, fpSrc, 
                    new int[]{GLShaderManager.GL_ATTRIBUTE_VERTEX,GLShaderManager.GL_ATTRIBUTE_NORMAL}, 
                    new String[]{"vVertex","vNormal"});
            
            iAmbientColor = GLES20.glGetUniformLocation(curProgram, "ambientColor");
            iDiffuseColor = GLES20.glGetUniformLocation(curProgram, "diffuseColor");
            iSpecularColor = GLES20.glGetUniformLocation(curProgram, "specularColor");
            iLightPostion = GLES20.glGetUniformLocation(curProgram, "lightPostion");
            iNormalMatrix = GLES20.glGetUniformLocation(curProgram, "normalMatrix");
            iMvMatrix = GLES20.glGetUniformLocation(curProgram, "mvMatrix");
            iMvpMatrix = GLES20.glGetUniformLocation(curProgram, "mvpMatrix");
        }

        private void initData() {
            torusBatch=new GLTriangleBatch();
            boolean cached = torusBatch.loadDataFromSD("torus");
            if (!cached) {
                torusBatch=GLTools.makeTorus(0.5f, 0.1f, 52, 52);
                torusBatch.cacheDataToSD("torus");
            }
        }
        
        private int curProgram;
        private GLTriangleBatch torusBatch;
        private float[] ambientColor={0.3f,0.3f,0.3f,1.0f};
        private float[] diffuseColor={0.8f,0.8f,0.0f,1.0f};
        private float[] specularColor={1.0f,1.0f,0.0f,1.0f};
        private float[] lightPostion={0.0f,3.0f,1.0f};
        private GLMatrixStack mvMatrix=new GLMatrixStack();
        private GLMatrixStack projectionMatrix=new GLMatrixStack();
        private GLGeometryTransform transformPipleLine=new GLGeometryTransform();
        private int iAmbientColor;
        private int iDiffuseColor;
        private int iSpecularColor;
        private int iLightPostion;
        private int iNormalMatrix;
        private int iMvMatrix;
        private int iMvpMatrix;
    }
}
